#include <stdio.h>
#include <sqlite3.h>
#include <pthread.h>

#include "shmem.h"

#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/types.h> /* See NOTES */
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "cJSON.h"
int acceptfd ;
int sockfd;
 float buf[229] = {};

static struct shm_param para;

union val_t
{ 
    int b_val;  //bool类型存储空间
    int i_val;   //整形值存储空间
    float f_val;  //浮点值存储空间
};

struct student
{
    char str[64]; //可以存放所有字符型
    int key;  //唯一键值
    int type;  //数据点类型
    int dev_type;  //数据点属于哪个设备，根据网关支持的设备自行定义
    union val_t old_val;  //变化上报后需要更新旧值
    union val_t new_val;  //从共享内存取出最新数据，放到new_val中
    int ret;  //默认为-1，采集成功后设置为0，采集失败再置-1
};

static int *total;  //指向共享内存中数据节点总个数
static struct student *node_arr;  //指向共享内存中节点缓存数组头

#define MAX_NODE 50  //最大支持学生数目
#define STD_NODE_LEN sizeof(struct student)
#define MAX_NODE_SIZE (MAX_NODE * STD_NODE_LEN)


int flag4=0;
sqlite3 *db;
char *errmsg;
int callback(void *para, int f_num, char **f_value, char **f_name)
{
    // printf("%s\n", (char *)para); // hello
    for (int i = 0; i < f_num; i++)
    {
        printf("%s ", f_name[i]); // id score
    }
    printf("\n");
    for (int i = 0; i < f_num; i++)
    {
        printf("%s ", f_value[i]); // 1 98.5
    }
    printf("\n");
    return 0;
}

void *handler_thread2(void *arg)
{
    
while (1)
{
    //sleep(5);
    if (flag4==1)
    {
    
    char **result = NULL;
    int hang, lie;
    int i, j,k=0;
    if (sqlite3_get_table(db, "select id,score,id1,score1 from stu1;", &result, &hang, &lie, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "stu1 select err:%s\n", errmsg);
       // return -1;
       sqlite3_free_table(result);
        return -1 ;
    }
    printf("%d %d\n", hang, lie);
    // int id_to_query = 101;
    // get_score_by_id(db, id_to_query);
    printf("-----------------85\n");
    for (i = 0; i < hang + 1; i++)
    {
        int h=0;
        for (j = 0; j < lie; j++)
        {
          //  printf("%s ",result[k++]);
            buf[h]=atof(result[k++]);
             h++;
        }
      
         printf("%.2f ",buf[0]);
         printf("%.2f ",buf[1]);
          printf("%.2f ",buf[2]);
           printf("%.2f ",buf[3]);

 cJSON *root=cJSON_CreateObject();
 
 
 cJSON_AddItemToObject(root, "temp", cJSON_CreateNumber(buf[1]));
 cJSON_AddItemToObject(root, "hum", cJSON_CreateNumber(buf[3]));
  
 // 将 JSON 对象转为字符串并打印
char *json_string = cJSON_Print(root);  // 格式化输出（带换行缩进）
printf("JSON 输出:\n%s\n", json_string);
//send(acceptfd,json_string , 229, 0);

 int len = strlen(json_string);                    // 获取真实长度
    send(acceptfd, json_string, len, 0);              // 只发送有效数据
    send(acceptfd, "\n", 1, 0);                       // 添加换行符作为消息边界（关键！）
    free(json_string);  

      //sqlite3_free_table(result);

        printf("rrrrr\n");
       sleep(3);
    }
//flag4=0;
    }
}

 


}

void *handler_thread3(void *arg)
{
  sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket err:");
        return -1;
    }

    // 2.填充结构体信息
    struct sockaddr_in addr, caddr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi("7666"));
    // addr.sin_addr.s_addr = inet_addr(argv[1]);
    // addr.sin_addr.s_addr = inet_addr("0.0.0.0");
    addr.sin_addr.s_addr = INADDR_ANY;
    socklen_t len = sizeof(addr);
    // 3.绑定
    int ret = bind(sockfd, (struct sockaddr *)&addr, len);
    if (ret < 0)
    {
        perror("bind err:");
        return -1;
    }

    // 4. 监听
    if (listen(sockfd, 5) < 0)
    {
        perror("listen err");
        return -1;
    }

    while (1)
    {
        // 5.阻塞等待客户端连接
         acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);
        if (acceptfd < 0)
        {
            perror("accept err");
            return -1;
        }
        printf("accept ok\n");
        printf("client ip:%s,port:%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
       flag4=1;
        // 6.接收
        char buf1[128] = {};
        while (1)
        {
            ret = recv(acceptfd, buf1, 128, 0);
            if (ret < 0)
            {
                perror("recv err:");
                return -1;
            }
            else if (ret == 0)
            {
                printf("client exit\n");
                break;
            }
          //  printf("recv:%s  \n", buf);
        }

        
    }
  
//sleep(3);


}
int main(int argc, char const *argv[])
{





int ret = -1;

    ret = shm_init(&para, "shm_test", MAX_NODE_SIZE);
    if(ret < 0)
    {
        return -1;
    }


    void *node_p = shm_getaddr(&para);
    if(node_p == NULL)
    {
        return -1;
    }

    //前4个字节存储实际的学生数目
    total = (int *)node_p;
    //后面空间存储数据点
    node_arr = (struct student *)(node_p + sizeof(int));



 pthread_t tid;
    if (pthread_create(&tid, NULL, handler_thread2, NULL) != 0)
    {
        perror("pthread create err");
        return -1;
    }
    printf("main\n");



    pthread_t tid1;
    if (pthread_create(&tid1, NULL, handler_thread3, NULL) != 0)
    {
        perror("pthread create err");
        return -1;
    }
    printf("main1\n");

db = NULL;

    // 1.打开或创建数据库
    if (sqlite3_open("./stu.db", &db) != SQLITE_OK)
    {
        fprintf(stderr, "sqlite3_open err:%s\n", sqlite3_errmsg(db));
        return -1;
    }
    errmsg = NULL;

    // 2.创建一个表
    if (sqlite3_exec(db, "create table stu1(id int,score float,id1 int,score1 float);", NULL, NULL, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "stu1 create err:%s\n", errmsg);
        // return -1;
    }
    printf("create ok\n");

    // 3.向表中插入数据
    int id;
    char name[32] = {0};
    char sql[229] = {0};
    float score;
    printf("pls input student number:");
    int n = 0;
    scanf("%d", &n); // 2
    printf("pls input id name score:\n");
   
    
    while (1)
    {
        //if (flag4==0)
       // {
             //scanf("%d %s %f", &id, name, &score);
//sleep(5);


    sprintf(sql, "insert into stu1 values(%d,%.2f,%d,%.2f);", node_arr[9].key, node_arr[9].new_val.f_val,node_arr[10].key, node_arr[10].new_val.f_val);
        if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
        {
            fprintf(stderr, "stu1 insert err:%s\n", errmsg);
            return -1;
       
        }

sleep(1);
        
   //  flag4=1;
     //   }
        
       
    }
    
        
   sqlite3_close(db);
if (remove("stu.db") == 0) {
    printf("数据库已安全删除\n");
} else {
    perror("删除失败");
}
return 0;
    // 4.查找表中的数据

    // if (sqlite3_exec(db, "select id,score from stu1;", callback, "hello", &errmsg) != SQLITE_OK)
    // {
    //     fprintf(stderr, "stu1 select err:%s\n", errmsg);
    //     return -1;
    // }

    // 查询
   
    //5.关闭数据库
  
}




